import * as fs from "fs";
import * as path from "path";


import {getReadableDate} from "finch-tools";


/***
 * 定义可绘制的颜色
 */
enum FinchLogger_Color
{
    green,
    red,
    yellow,
    yellowBG,
    redBG
}


interface FinchLogger_Option
{
    maxLines?: number
    maxFiles?: number
    enableConsoleLog?: boolean
    enableFileLog?: boolean
    logStorageDir?: string
}


/**
 * 打印日志类
 */
class FinchLogger
{
    private readonly _maxLines: number = 2000;
    private readonly _maxFiles: number = 500;
    private readonly _enableConsoleLog: boolean = true;
    private readonly _enableFileLog: boolean = true;
    private readonly _logStorageDir: string = "./finch_log";

    private _createNewLogFile: boolean = true;
    private _currentWriteStream: fs.WriteStream = undefined;
    private _currentFileLineCount = 0;

    constructor(option?: FinchLogger_Option)
    {
        if (!option) return;
        if (option.maxFiles) this._maxFiles = option.maxFiles;
        if (option.maxFiles) this._maxLines = option.maxLines;
        if (option.enableConsoleLog) this._enableConsoleLog = option.enableConsoleLog;
        if (option.enableFileLog) this._enableFileLog = option.enableFileLog;
        if (option.logStorageDir) this._logStorageDir = option.logStorageDir;
    }


    //如果日志总数大于之前设定的日志，则删除多的文件
    private delLog()
    {
        if (!fs.existsSync(this._logStorageDir))
        {
            return;
        }
        let list = fs.readdirSync(this._logStorageDir);
        while (list.length > this._maxFiles)
        {
            let f = null;
            for (let a in list)
            {
                if (path.extname(list[a]) === '.txt')
                {
                    f = list[a];
                    fs.unlinkSync(path.join(this._logStorageDir, f));
                    break;
                }
            }
            list = fs.readdirSync(this._logStorageDir);
        }
    }

    /**
     * 日志API
     * @param message 信息
     * @param color 颜色（可选）
     */
    public log(message: string, color?: FinchLogger_Color)
    {
        let messageString = message;
        let timeStamp = getReadableDate();

        if (this._enableConsoleLog)
            console.log(paint(timeStamp, FinchLogger_Color.yellow) + " : " + paint(messageString, color));

        if (this._enableFileLog)
        {
            if (!fs.existsSync(this._logStorageDir)) fs.mkdirSync(this._logStorageDir, {recursive:true});
            if (this._createNewLogFile)
            {
                this.delLog();
                this._currentWriteStream = fs.createWriteStream(path.join(this._logStorageDir, timeStamp + ".txt"), {flags: 'a'});
                this._createNewLogFile = false;
            }
            if (this._currentWriteStream)
            {
                let theInfo = timeStamp + ' : ' + message;
                this._currentWriteStream.write(theInfo + '\r\n');
                this._currentFileLineCount++;
                if (this._currentFileLineCount > this._maxLines)
                {
                    this._currentWriteStream.end();
                    this._createNewLogFile = true;
                    this._currentFileLineCount = 0;
                }
            }
        }
    }


    public logInfo(message: string)
    {
        this.log(`[---INFO---] : ${message}`);
    }

    public logWarning(message: string)
    {
        this.log(`[-WARNING!-] : ${message}`, FinchLogger_Color.yellow);
    }

    public logError(message: string)
    {
        this.log(`[--ERROR!--] : ${message}`, FinchLogger_Color.red);
    }


}


/***
 * 绘制颜色的方法
 * @param message 原始信息
 * @param color 增加颜色后的信息
 */
function paint(message: string, color?: FinchLogger_Color): string
{
    let logColorStyler = [
        ['\x1B[32m', '\x1B[39m'],
        ['\x1B[31m', '\x1B[39m'],
        ['\x1B[33m', '\x1B[39m'],
        ['\x1B[43m', '\x1B[49m'],
        ['\x1B[41m', '\x1B[49m']
    ];
    if (color !== undefined)
    {
        return logColorStyler[color][0] + message + logColorStyler[color][1] + " ";
    }
    else return message;
}



export {FinchLogger, FinchLogger_Color};